package cn.joeg.app.css.util;

import com.ecfront.dew.common.JsonHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.persistence.Query;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class DBHelper {

    private static final Logger logger = LoggerFactory.getLogger(DBHelper.class);

    public static <T> List<T> getResultList(Query query, Class<T> type) {
        List<T> resultList = new ArrayList<>();
        try {
            if (query == null) {
                return resultList;
            }
            @SuppressWarnings("unchecked")
            List<Object[]> records = query.getResultList();
            logger.info("DBHelper input : {}", JsonHelper.toJson(records));
            resultList = map(type, records);
            logger.info("DBHelper output : {}", JsonHelper.toJson(records));
        } catch (Exception e) {
            logger.error("getResultList error : {}", e.getMessage());
            return resultList;
        }
        return resultList;
    }

    public static <T> List<T> map(Class<T> type, List<Object[]> records) {
        List<T> result = new LinkedList<>();
        for (Object[] record : records) {
            result.add(map(type, record));
        }
        return result;
    }

    private static <T> T map(Class<T> type, Object[] tuple) {
        List<Class<?>> tupleTypes = new ArrayList<>();
        for (Object field : tuple) {
            if (field == null) {
                Field[] fields = type.getDeclaredFields();
                String fieldType = fields[tupleTypes.size()].getGenericType().toString(); //获取属性的类型
                if (fieldType.equals("class java.lang.String")) { //如果type是类类型，则前面包含"class "，后面跟类名
                    field = "";
                } else if (fieldType.equals("class java.math.BigDecimal")) {
                    field = new BigDecimal(0);
                } else {
                    field = "";
                }
            }
            tupleTypes.add(field.getClass());
        }
        try {
            Constructor<T> ctor = type.getConstructor(tupleTypes.toArray(new Class<?>[tuple.length]));
            return ctor.newInstance(tuple);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}
